package com.dongzili.query.common.utils;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReflectUtils {

    private static final Logger logger = LoggerFactory.getLogger(ReflectUtils.class);

    /**
     * 判断实体类是否包含所有字段,并返回不存在的字段名
     * @param fieldNames
     * @param clazz
     * @return
     * @param <T>
     */
    public static <T> List<String> getNotExistsFields(List<String> fieldNames, Class<T> clazz) {
        List<String> names = new ArrayList<>();
        for (String fieldName : fieldNames) {
            try {
                Field field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
//                return false; // 如果找不到字段，返回false
                names.add(fieldName);
            }
        }
        return names; // 所有字段都存在，返回true
    }

    /**
     * 复制关键字段
     * @param oldObject
     * @param fieldNames
     * @param clazz
     * @return
     * @param <T>
     * @throws Exception
     */
    public static <T> T copyKeyFields(T oldObject, List<String> fieldNames, Class<T> clazz) {
        try{
            T newObject = clazz.getDeclaredConstructor().newInstance();
            for (String fieldName : fieldNames) {
                Field field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                Object value = field.get(oldObject);
                field.set(newObject, value);
            }

            // 检查并复制带有 @TableId 注解的字段
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(TableId.class)) {
                    field.setAccessible(true);
                    Object value = field.get(oldObject);
                    if (value != null) {
                        field.set(newObject, value);
                    }
                }
            }
            return newObject;
        }catch (Exception e){
            logger.error("复制关键字段异常",e);
        }
        return null;
    }

    /**
     * 复制ID字段
     * @param oldObject
     * @param clazz
     * @return
     * @param <T>
     * @throws Exception
     */
    public static <T> void copyIdField(T oldObject, T newObject, Class<T> clazz){
        try{
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(TableId.class)) {
                    field.setAccessible(true);
                    Object value = field.get(oldObject);
                    if (value != null) {
                        field.set(newObject, value);
                    }
                }
            }
        }catch (Exception e){
            logger.error("复制ID字段异常",e);
        }
    }

    /**
     * 判断实体类ID字段是否有值
     * @param oldObject
     * @return
     * @param <T>
     * @throws Exception
     */
    public static <T> boolean hasIdValue(T oldObject) {
        try{
            for (Field field : oldObject.getClass().getDeclaredFields()) {
                if (field.isAnnotationPresent(TableId.class)) {
                    field.setAccessible(true);
                    Object value = field.get(oldObject);
                    if (value != null) {
                        return true;
                    }
                }
            }
        }catch (Exception e){
            logger.error("判断实体类ID字段是否有值异常",e);
        }
        return false;
    }


    /**
     * 获取不为空的属性的数据库字段名和值
     * @param obj
     * @return
     */
    public static Map<String, Object> getNotNullFieldValueMap(Object obj) {
        Map<String, Object> fieldValueMap = new HashMap<>();
        if (obj == null){
            return fieldValueMap;
        }
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                if (tableFieldAnnotation != null && !tableFieldAnnotation.exist()) {
                    continue; // Ignore if exist is false
                }
                Object value = field.get(obj);
                if (value != null) {
                    fieldValueMap.put(getFieldName(field), value);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return fieldValueMap;
    }

    /**
     * 获取实体属性的数据库字段名称
     * @param field
     * @return
     */
    public static String getFieldName(Field field) {
        TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
        if (tableFieldAnnotation != null && !tableFieldAnnotation.value().isEmpty()) {
            return tableFieldAnnotation.value();
        } else {
            return field.getName();
        }
    }


}
